package com.ntf.games.framework;

//-
//- Vector3f.java
//-
import java.lang.Math;

//-
//- @author Me
//-
//- 
//-
public class Vector3d
{
  // //////////////////////
  // - Member Data
  public double x, y, z;

  // //////////////////////
  // - Member Functions
  public Vector3d( double _x, double _y, double _z)
  {
    this.x = _x;
    this.y = _y;
    this.z = _z;
  }

  // //////////////////////
  // -
  public Vector3d( Vector3d _vec)
  {
    this.x = _vec.x;
    this.y = _vec.y;
    this.z = _vec.z;
  }

  // //////////////////////
  // -
  public Vector3d()
  {
    this.x = 0.0f;
    this.y = 0.0f;
    this.z = 0.0f;
  }

  // //////////////////////
  // -
  void Scale( double _scale)
  {
    this.x *= _scale;
    this.y *= _scale;
    this.z *= _scale;
  }

  // //////////////////////
  // Normalize a vector
  // Scale a vector to unit length. Easy, just scale the vector by it's length
  // inline void m3dNormalizeVector3(M3DVector3f u)
  // { m3dScaleVector3(u, 1.0f / m3dGetVectorLength3(u)); }
  void Normalize()
  {
    this.Scale( 1.0f / GetVectorLength( this));
  }

  // //////////////////////
  // - Subtracts vector v and returns result as new vector.
  // -
  // - @param v -- vector to be subtracted
  // - @return result as new vector
  // -
  public final Vector3d sub( Vector3d v)
  {
    return new Vector3d( this.x - v.x, this.y - v.y, this.z - v.z);
  }

  // //////////////////////
  // - Add vector v and returns result as new vector.
  // -
  // - @param v
  // - vector to add
  // - @return result as new vector
  // -
  public final Vector3d add( Vector3d v)
  {
    return new Vector3d( this.x + v.x, this.y + v.y, this.z + v.z);
  }

  // //////////////////////
  // - Calculates distance to another vector
  // -
  // - @param v -- non-null vector
  // - @return distance or Float.NaN if v=null
  // -
  public final double distanceTo( Vector3d v)
  {
    double dRetVal = 0;

    if( v != null)
    {
      double dx = x - v.x;
      double dy = y - v.y;
      double dz = z - v.z;
      dRetVal = Math.sqrt( dx * dx + dy * dy + dz * dz);
    }
    return(dRetVal);
  }

  // //////////////////////
  // Get Square of a vectors length
  // Only for three component vectors
  double GetVectorLengthSquared( Vector3d u)
  {
    return((u.x * u.x) + (u.y * u.y) + (u.z * u.z));
  }

  // //////////////////////
  // Get Square of a vectors length
  // Only for three component vectors
  double GetVectorLengthSquared()
  {
    return(this.GetVectorLength( this));
  }

  // //////////////////////
  // Get lenght of vector
  // Only for three component vectors.
  double GetVectorLength( Vector3d u)
  {
    return((double )Math.sqrt( (double )GetVectorLengthSquared( u)));
  }

  // //////////////////////
  // Cross Product
  // u x v = result
  // 2 component vectors only.
  public static Vector3d crossProduct( Vector3d u, Vector3d v)
  { // 0=x, 1=y, 2=z
    Vector3d result = new Vector3d();
    result.x = u.y * v.z - v.y * u.z;
    result.y = -u.x * v.z + v.x * u.z;
    result.z = u.x * v.y - v.x * u.y;

    return(result);
  }

}
